package org.particles.domain.sim;

import java.util.List;

import org.particles.common.CommonUtil;
import org.particles.domain.field.AbstractField;
import org.particles.domain.world.FieldRepository;

/**
 * atom grid simulation in 2D.
 */
public class ElectronSimulation extends AbstractSimulationCase {
	public static final int PARAM_FIELD_STRENGTH = CommonUtil.uniqueIndex();
	/** distance to field strength zero */
	public static final int PARAM_DIST_TO_ZERO = CommonUtil.uniqueIndex();
	protected AbstractField magneticField;
	protected static final long fieldMarker = FieldRepository.REJECT_LIN;

	public ElectronSimulation() {
		super();
		setName("Atom grid");
		setWorldWidth(800);
		setWorldHeight(600);
		setNumberParticles(70);
		setFieldMarkers(fieldMarker);
		magneticField = (AbstractField) 
				getFieldRepository().getField(fieldMarker);
		magneticField.getDistanceFunc().setFactor(100);
		magneticField.setStrength(20);
	}
	
	@Override
	public boolean changeParam(int paramCode, double newValue) {
		if(super.changeParam(paramCode, newValue)) {
			return true;
		}
		else {
			if(PARAM_FIELD_STRENGTH == paramCode) {
				setFieldStrength(newValue); 
				return true;
			}
			else if(PARAM_DIST_TO_ZERO == paramCode) {
				setDistToZero(newValue); 
				return true;
			}
			else {
				return false;
			}
		}
	}

	@Override
	public List<SimParam> availableParams() {
		final List<SimParam> params = super.availableParams();
		SimParam param;
		param = new SimParam(PARAM_FIELD_STRENGTH, "magnetic field strength", getFieldStrength());
		param.setMinValue(0D);
		param.setMaxValue(1000D);
		params.add(param);
		param = new SimParam(PARAM_DIST_TO_ZERO, "magnetic zero distance", getDistToZero());
		param.setMinValue(0D);
		param.setMaxValue(1000D);
		param.setDesc("from which distance magnetic field strength goes to zero");
		params.add(param);
		return params;
	}

	public void setFieldStrength(double fieldStrength) {
		this.magneticField.setStrength(fieldStrength);
	}

	/** 
	 * distance to field strength zero.
	 * overridden to be able to change distToZero on the fly. 
	 */
	public void setDistToZero(final double distToZero) {
		magneticField.getDistanceFunc().setFactor(distToZero);
	}
	
	/** distance to field strength zero */
	public double getDistToZero() {
		return magneticField.getDistanceFunc().getFactor();
	}

	public double getFieldStrength() {
		return this.magneticField.getStrength();
	}
	
}
